package com.zmzncs.lmtc.module.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zmzncs.lmtc.common.pojo.Rest;
import com.zmzncs.lmtc.common.pojo.enums.optionalvalue.promotion.ReserveRecordStatusEnum;
import com.zmzncs.lmtc.common.util.WeChatUtil;
import com.zmzncs.lmtc.common.pojo.LoginUser;
import com.zmzncs.lmtc.common.util.*;
import com.zmzncs.lmtc.module.customer.dao.CustomerDao;
import com.zmzncs.lmtc.module.customer.pojo.customer.CustomerDTO;
import com.zmzncs.lmtc.module.order.dao.ParkReserveRecordDao;
import com.zmzncs.lmtc.module.order.pojo.order_reserve.*;
import com.zmzncs.lmtc.module.order.service.ParkReserveRecordService;
import com.zmzncs.lmtc.module.park.dao.ParkInfoDao;
import com.zmzncs.lmtc.module.park.pojo.parkinfo.ParkInfo;
import com.zmzncs.lmtc.module.promotion.dao.ReserveRuleDao;
import com.zmzncs.lmtc.module.promotion.dao.ReserveTemporaryRuleDao;
import com.zmzncs.lmtc.module.promotion.pojo.Reserve_temporary_rule.ReserveTemporaryRuleDTO;
import com.zmzncs.lmtc.module.promotion.pojo.reserve_rule.ReserveRuleDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


/**
 * <p>
 * 预约记录表 服务实现类
 * </p>
 *
 * @author 任建波
 * @since 2020-12-14
 */
@Service
@Slf4j
public class ParkReserveRecordServiceImpl extends ServiceImpl<ParkReserveRecordDao, ParkReserveRecord> implements ParkReserveRecordService {

    @Autowired
    private ParkReserveRecordDao parkReserveRecordDao;
    @Autowired
    private ParkInfoDao parkInfoDao;
    @Autowired
    private CustomerDao customerDao;
    @Autowired
    ReserveRuleDao reserveRuleDao;
    @Autowired
    HttpServletRequest request;
    @Autowired
    private ReserveTemporaryRuleDao reserveTemporaryRuleDao;
    //
    private  String buyReserveUrl;
    @Value("${pay-test}")
    boolean payTest;


    @Override
    public IPage<ParkReserveRecordDTO> page(ParkReserveRecordSearchForm form){
        LoginUser loginUser = JwtUtil.getLoginUser(request);
        IPage<ParkReserveRecordDTO> iPage = parkReserveRecordDao.list(form.getPage(), loginUser.getCustomerId(), null);

        return iPage;
    }

    @Override
    public IPage<ParkReserveRecordDTO> getReserveRecord(Integer pageNum, Integer pageSize,Integer status) {
        Long customerId = JwtUtil.getLoginUser(request).getCustomerId();
        Page page = new Page(pageNum, pageSize);
        IPage<ParkReserveRecordDTO> iPage = null;
        if(status==1){
            iPage = parkReserveRecordDao.getReserveRecord(page,customerId);
        }else if(status==2){
            iPage = parkReserveRecordDao.getAlreadyReserveRecord(page,customerId);
        }
        if (iPage != null){
            List<ParkReserveRecordDTO> records = iPage.getRecords();
            for (ParkReserveRecordDTO recordDTO : records) {
                recordDTO.setSubmitTime(recordDTO.getCreateTime());
                String beginTime = DateTimeUtil.convertYMDHMS(recordDTO.getReserveBeginTime());
                String endTime = DateTimeUtil.convertYMDHMS(recordDTO.getReserveEndTime());
                String reserveTime = beginTime.substring(0, 16) + "-" + endTime.substring(11,16);
                recordDTO.setReserveTime(reserveTime);
            }
        }
        return iPage;
    }

    /**
     * 查询当前成功的预约
     */
    @Override
    @Transactional
    public List<ParkReserveRecordDTO> reservedCurr() {
        LoginUser loginUser = JwtUtil.getLoginUser(request);

        List<ParkReserveRecordDTO> list = parkReserveRecordDao.list(loginUser.getCustomerId(), 2);

        //  处理预约超时
        Iterator<ParkReserveRecordDTO> iterator = list.iterator();
        while (iterator.hasNext()) {
            ParkReserveRecordDTO recordDTO = iterator.next();
            //  预约超时
            if (recordDTO.getReserveEndTime().getTime() < new Date().getTime()) {
                ParkReserveRecord parkReserveRecord = new ParkReserveRecord();
                parkReserveRecord.setId(recordDTO.getId());
                parkReserveRecord.setStatus(ReserveRecordStatusEnum.PARKALLOW_CUSTOMERCANCEL.getCode());
                parkReserveRecordDao.updateById(parkReserveRecord);

                iterator.remove();//使用迭代器的删除方法删除
            }
        }

        return list;
    }

    /**
     * 预约
     */
    @Override
    public Map<String, Object> reserve(ParkReserveRecordAddForm form){
        //  预约规则
        ReserveRuleDTO ruleDTO = reserveRuleDao.getByParkId(form.getParkId());
        if(ruleDTO == null) {
            ExceptionUtil.businessException("停车场暂无开放预约功能");
        }

        //  查询停车场
        ParkInfo parkInfo = parkInfoDao.selectById(form.getParkId());
        //临时可预约
        ReserveTemporaryRuleDTO reserveTemporaryRuleDTO = reserveTemporaryRuleDao.getByDate(form.getParkId(),DateTimeUtil.convertYMD(form.getReserveBeginTime()));
        //根据日期查询预约成功的预约记录
        List<ParkReserveRecordDTO>  parkReserveRecordDTOS = parkReserveRecordDao.getReserveRecordByReserveDate(form.getParkId(), form.getReserveBeginTime());
        //  可预约车位数
        int reserveSpace = parkInfo.getReserveParkSpace();
        if(reserveTemporaryRuleDTO != null){
            reserveSpace = reserveTemporaryRuleDTO.getReserveSpace();
        }
        //  规则预约车位数 减去 已预约车位数
        reserveSpace = reserveSpace - parkReserveRecordDTOS.size();
        if( reserveSpace <= 0 ){
            ExceptionUtil.businessException("预约车位不充足");
        }

        if(form.getReserveBeginTime() !=null && (DateTimeUtil.getCurrAfterMinuteDate(new Date(),30).getTime() >=  form.getReserveBeginTime().getTime())  ){
            ExceptionUtil.businessException("已临近入场时间，请预约其他时间段！");
        }

        LoginUser loginUser = JwtUtil.getLoginUser(request);
        //  查询客户
        CustomerDTO customerDTO = customerDao.getCustomerById(loginUser.getCustomerId());
        //  订单号
        String orderCode = ChinaumsUtil.getMerOrderId("YY");  //    订单号

        ParkReserveRecord parkReserveRecord = new ParkReserveRecord();
        BeanUtils.copyProperties(form, parkReserveRecord);
        parkReserveRecord.setTradeNo(orderCode);
        parkReserveRecord.setCustomerId(loginUser.getCustomerId());
        parkReserveRecord.setMobilePhone(customerDTO.getMobilePhone());
        parkReserveRecord.setStatus(ReserveRecordStatusEnum.SUBMITTING.getCode());
        parkReserveRecordDao.insert(parkReserveRecord);

        //  支付
        JSONObject attach = new JSONObject();
        attach.put("customerId", loginUser.getCustomerId());
        BigDecimal reserveAmount = payTest ? new BigDecimal("0.01") : form.getReserveAmount();

        return WeChatUtil.wxPay(customerDTO.getOpenid(), buyReserveUrl, reserveAmount, orderCode, attach.toJSONString(), "预约车位");
    }


    /**
     * 预约支付通知
     */
    @Override
    @Transactional
    public String payReserveNotice(String callbackStr) {
        //  解析微信返回值
        Map<String, String> callbackMap = null;
        try {
            callbackMap = XmlUtil.parseXML(callbackStr);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 支付成功
        if ("SUCCESS".equals(callbackMap.get("return_code")) && "SUCCESS".equals(callbackMap.get("result_code"))) {
            //  修改购买会员卡订单状态
            String orderCode = callbackMap.get("out_trade_no");    //  订单号
            log.info("订单号：" + orderCode);

            ParkReserveRecordDTO reserveRecordDTO = parkReserveRecordDao.getByTradeNo(orderCode);
            //  重复通知
            if(reserveRecordDTO.getPayStatus().equals(2)){
                log.info("重复通知");
                return WeChatUtil.wxpayCallbackResult(true);
            }

            ParkReserveRecord parkReserveRecord = new ParkReserveRecord();
//            parkReserveRecord.setStatus(1);
            parkReserveRecord.setPayStatus(2);

            LambdaUpdateWrapper<ParkReserveRecord> updateWrapper = new LambdaUpdateWrapper();
            updateWrapper.eq(ParkReserveRecord::getTradeNo, orderCode);
            parkReserveRecordDao.update(parkReserveRecord, updateWrapper);

            log.info("------------预约支付通知-微信支付回调结束");
        }
        return WeChatUtil.wxpayCallbackResult(true);
    }

    /**
     * 取消预约
     */
    @Override
    @Transactional
    public Rest cancelReserve(Long id) {
        ParkReserveRecordDTO parkReserveRecordDTO = parkReserveRecordDao.getById(id);
        // 只有C端申请 校验。
        if(parkReserveRecordDTO.getChargebackTime()!=null
             && parkReserveRecordDTO.getChargebackTime().getTime()<=new Date().getTime()){
            RestUtil.error("超过最后可退款时间，不可取消！");
        }

        //  微信退款申请
        String tradeNo = WeChatUtil.generateTradeNo();
        ParkReserveRecord parkReserveRecord = new ParkReserveRecord();
        parkReserveRecord.setId(id);

        Map result = WeChatUtil.refund(tradeNo, parkReserveRecordDTO.getReserveAmount(), parkReserveRecordDTO.getReserveAmount(), parkReserveRecordDTO.getTradeNo(), "取消预约");
        if(result != null && result.get("resultCode").equals("SUCCESS")){
            Integer reserveStatus =
                            (parkReserveRecordDTO.getStatus()!=null
                            && parkReserveRecordDTO.getStatus().intValue()==ReserveRecordStatusEnum.ALLOW.getCode())
                            ?ReserveRecordStatusEnum.PARKWAIT_CUSTOMERCANCEL.getCode()
                            :ReserveRecordStatusEnum.PARKALLOW_CUSTOMERCANCEL.getCode();
            parkReserveRecord.setStatus(reserveStatus);
        } else {
            ExceptionUtil.businessException(result.get("errCodeDes").toString());
        }

        parkReserveRecordDao.updateById(parkReserveRecord);
        return RestUtil.success();
    }

//    @Override
//    public void delete(Long id){
//        ParkReserveRecord parkReserveRecord = new ParkReserveRecord();
//        parkReserveRecord.setId(id);
//        parkReserveRecord.setisisDeleted(1);
//
//        parkReserveRecordDao.updateById(parkReserveRecord);
//    }

//    @Override
//    public void update(ParkReserveRecordUpdateForm form){
//        ParkReserveRecord parkReserveRecord = new ParkReserveRecord();
//        BeanUtils.copyProperties(form, parkReserveRecord);
//
//        parkReserveRecordDao.updateById(parkReserveRecord);
//    }

    @Override
    public ParkReserveRecordDTO getById(Long id){
        ParkReserveRecordDTO parkReserveRecordDTO = parkReserveRecordDao.getById(id);

        return parkReserveRecordDTO;
    }

    @Override
    @Transactional
    public void updateStatusByCarNumber(String carNumber, Long parkId, Date inTime,Long orderId) {
        //查询是否需要更新状态预约记录
        ParkReserveRecordDTO parkReserveRecordDTO = parkReserveRecordDao.getRecordByCarNumber(carNumber, parkId, inTime);
        if (parkReserveRecordDTO != null){

            ParkReserveRecord reserveRecord = new ParkReserveRecord();
            reserveRecord.setId(parkReserveRecordDTO.getId());
            reserveRecord.setOrderId(orderId);
            reserveRecord.setStatus(6);
            parkReserveRecordDao.updateById(reserveRecord);
        }

    }

    public String getBuyReserveUrl() {
        return buyReserveUrl;
    }
    @Value("${wechat.notify-url.buyReserveUrl}")
    public void setBuyReserveUrl(String buyReserveUrl) {
        this.buyReserveUrl = buyReserveUrl;
    }
}
